package com.central.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.central.common.model.Result;
import com.central.common.model.SysRole;
import com.central.common.model.SysUser;
import com.central.common.service.impl.SuperServiceImpl;
import com.central.project.constant.ProjectConstant;
import com.central.project.mapper.ProUserRoleMapper;
import com.central.common.model.ProUserRole;
import com.central.project.service.IProUserRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author Tindy
 * @date 2021/6/24
 * @describe
 */
@Slf4j
@Service
public class ProUserRoleServiceImpl extends
        SuperServiceImpl<ProUserRoleMapper, ProUserRole> implements IProUserRoleService {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateProAdmins(Long proId, Set<Long> userIds) {
        HashMap<String, Object> delMap = new HashMap<>();
        delMap.put("pro_id",proId);
        delMap.put("role_id", ProjectConstant.PRO_ADMIN_ROLE_ID);
        baseMapper.deleteByMap(delMap);
        ArrayList<ProUserRole> proUserRoles = new ArrayList<>();
        for (Long userId : userIds) {
            proUserRoles.add(new ProUserRole(proId,userId, ProjectConstant.PRO_ADMIN_ROLE_ID));
        }
        saveBatch(proUserRoles);
    }

    @Override
    public List<ProUserRole> findRolesByUserId(Long proId, Long userId) {
        return baseMapper.selectList(new QueryWrapper<ProUserRole>().eq("pro_id",proId).eq("user_id",userId));
    }

    @Override
    public List<ProUserRole> findRolesByProId(Long proId) {
        return baseMapper.selectList(new QueryWrapper<ProUserRole>().eq("pro_id",proId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result addProMenbers(Long currentProjectId, Long userId) {
        //判断用户是否是项目成员
        if(baseMapper.selectCount(new QueryWrapper<ProUserRole>().eq("pro_id",currentProjectId).eq("user_id",userId))>0){
            return Result.failed("该用户为项目成员，无需添加");
        }
        //默认新成员为开发者角色
        baseMapper.insert(new ProUserRole(currentProjectId,userId,ProjectConstant.DEV_USER_ROLE_ID));
        return Result.succeed("操作成功");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result delProMenbers(Long currentProjectId, Long userId) {
        //判断项目中除了该用户还有其他项目管理员角色用户
        if(baseMapper.selectCount(new QueryWrapper<ProUserRole>().eq("pro_id",currentProjectId).eq("role_id",ProjectConstant.PRO_ADMIN_ROLE_ID).ne("user_id",userId))==0){
            return Result.failed("操作失败，项目中必须存在至少一个项目管理员");
        }
        baseMapper.delete(new QueryWrapper<ProUserRole>().eq("pro_id",currentProjectId).eq("user_id",userId));
        return Result.succeed("操作成功");
    }

    @Override
    public Result updateProMenberRole(Long currentProjectId, Long userId, Set<Long> roles) {
        //判断项目中除了该用户还有其他项目管理员角色用户
        if(!roles.contains(ProjectConstant.PRO_ADMIN_ROLE_ID) && baseMapper.selectCount(new QueryWrapper<ProUserRole>().eq("pro_id",currentProjectId).eq("role_id",ProjectConstant.PRO_ADMIN_ROLE_ID).ne("user_id",userId))==0){
            return Result.failed("操作失败，项目中必须存在至少一个项目管理员");
        }
        //删除旧角色
        baseMapper.delete(new QueryWrapper<ProUserRole>().eq("pro_id",currentProjectId).eq("user_id",userId));
        //添加新角色
        ArrayList<ProUserRole> proUserRoles = new ArrayList<>();
        for (Long role : roles) {
            proUserRoles.add(new ProUserRole(currentProjectId,userId, role));
        }
        saveBatch(proUserRoles);
        return Result.succeed("操作成功");
    }

    /**
     * 判断成员中必须存在至少一个项目管理员
     * @param users
     * @return
     */
    private boolean checkProAdmin(List<SysUser> users) {
        for (SysUser user : users) {
            for (SysRole proRole : user.getProRoles()) {
                if(proRole.getId()==ProjectConstant.PRO_ADMIN_ROLE_ID) return true;
            }
        }
        return false;
    }
}
